/**
 * Created by PengWei on 2018/7/24.
 */

namespace mengdao {
    import EventDispatcher = egret.EventDispatcher;
    import Stage = egret.Stage;
    import DisplayObjectContainer = egret.DisplayObjectContainer;

    /**
     * 框架上下文
     * 总线，配置完成后由框架层自行将context传递
     * 除root\stage,仅context的事件派发属性和Injector对外暴露
     */
    export class Context extends EventDispatcher {

        /** 入口root */
        private _root: DisplayObjectContainer;

        /** 舞台 */
        private _stage: Stage;

        /** 注入器 */
        private _injector: Injector;

        /** 配置管理 */
        private _configManager: ConfigManager;

        /** 扩展安装 */
        private _extensionInstaller: ExtensionInstaller;

        /** 生命周期 */
        private _lifecycle: Lifecycle;

        /**
         * 获取注入器
         * @returns {mengdao.Injector}
         */
        public get injector(): Injector {
            return this._injector;
        }

        /**
         * 获得项目root
         * @returns {egret.DisplayObjectContainer}
         */
        public get root(): DisplayObjectContainer {
            return this._root;
        }

        /**
         * 获得舞台
         * @returns {egret.Stage}
         */
        public get stage(): Stage {
            return this._stage;
        }

        public constructor() {
            super();
            this.init();
        }

        /**
         * 绑定Root
         * @param {egret.DisplayObjectContainer} root
         * @returns {mengdao.Context}
         */
        public bindRoot(root: DisplayObjectContainer): Context {
            this._root = root;
            this._stage = this._root.stage;
            return this;
        }


        private init(): void {
            this._injector = new Injector(this);
            this._configManager = new ConfigManager(this);
            this._extensionInstaller = new ExtensionInstaller(this);
            this._lifecycle = new Lifecycle();
        }

        /**
         * 安装插件
         * @param {mengdao.IBundle | mengdao.IClass<mengdao.IBundle> | mengdao.IExtension | mengdao.IClass<mengdao.IExtension>} extensions
         * @returns {mengdao.Context}
         */
        public install(...extensions: Array<IBundle | IClass<IBundle> | IExtension | IClass<IExtension>>): Context {
            extensions.forEach(extensions => {
                this._extensionInstaller.install(extensions);
            }, this);
            return this;
        }

        /**
         * 配置传入参数
         * @param {mengdao.IConfig | mengdao.IClass<mengdao.IConfig>} configs : IConfig的实例或类名
         * @returns {mengdao.Context} 链式结构返回
         */
        public configure(...configs: Array<IConfig | IClass<IConfig>>): Context {
            configs.forEach(config => {
                this._configManager.addConfig(config);
            }, this);
            return this;
        }

        /**
         * 初始化
         * 派发初始化事件，象征预先进行的配置、扩展插件和常量绑定完毕
         */
        public initialize(): void {
            this.dispatchEventWith(ContextEvent.INITIALIZE);
            this._lifecycle.state = LifecycleState.ACTIVE;
        }

        //---------------------------------------------------------------------------------------------------------
        //                                               生命周期
        //---------------------------------------------------------------------------------------------------------
        public get isActive():boolean{
            return this._lifecycle.isActive;
        }

    }
}